/**
 * Package:com.goldcitynet.server.data.impl;
 * $Id$
 * Copyright(c) 2001-2005 www.afteryuan.com
 */
package com.afteryuan.server.data.impl;

import com.afteryuan.server.data.Room;
import com.afteryuan.server.data.Sprite;
import com.afteryuan.server.data.SpritePool;
import com.afteryuan.server.data.cache.JBossCacheFacoty;
import org.jboss.cache.Fqn;
import org.jboss.cache.Node;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


/**
 * SpritePoolJBossCacheImpl
 * <p/>
 * <p><a href="SpritePoolJBossCacheImpl.java.html"><i>View Source</i></a></p>
 * <pre>
 *             服务器的Sprite缓存空间组成
 *                      root
 *                       |
 *      ------------------------------------
 *      |                |                  |
 *  serverNode       instanceNode       dissociateNode
 *                       |
 *        ---------------------------------
 *        |              |                |
 *     sceneNode1     sceneNode2   sceneNode3
 *        |              |                 |
 *       ...        --------------         ...
 *                  |            |
 *      sceneInstance2-1    sceneInstance2-2 ...
 * <p/>
 * </pre>
 *
 * @author <a href="mailto:afteryuan@afteryuan.com">$Author$</a>
 * @version $Revision$
 */
public class SpritePoolJBossCacheImpl implements SpritePool {
    /*缓存的根目录*/
    private Node root;
    /*保存所有正常状态的Sprite*/
    private Node<String, Sprite> serverNode;
    /*保存所有正在移动的Sprite*/
    private Node<String, Sprite> movingNode;
    /*保存所有处于游离状态的Sprite,游离状态是指暂时离线,发生连接异常的Sprite,可能通过重连机制再次恢复正常状态*/
    private Node<String, Sprite> dissociateNode;
    /*分场景保存Sprite*/
    private Node sceneNode;

    public SpritePoolJBossCacheImpl(JBossCacheFacoty jBossCacheFacoty) {
        root = jBossCacheFacoty.getRoot();
        serverNode = root.addChild(Fqn.fromString("serverNode"));
        movingNode = root.addChild(Fqn.fromString("movingNode"));
        dissociateNode = root.addChild(Fqn.fromString("dissociateNode"));
        sceneNode = root.addChild(Fqn.fromString("sceneNode"));
    }

    public void addToServer(Sprite sprite) {
        /*放入serverNode节点*/
        serverNode.put(sprite.getId(), sprite);

    }

    public void addToGhost(Sprite sprite) {
        dissociateNode.put(sprite.getId(), sprite);
    }

    /**
     * 把sprite对象加入到对应的房间节点中
     *
     * @param sprite
     */
    public void addToRoom(Sprite sprite) {
        Fqn roomFqn = roomFqn(sprite.getRoom());
        Node<String, Sprite> roomNode = sceneNode.getChild(roomFqn);
        if (roomNode == null) roomNode = sceneNode.addChild(roomFqn);
        roomNode.put(sprite.getId(), sprite);
    }

    public void addToMoving(Sprite sprite) {
        movingNode.put(sprite.getId(), sprite);
    }

    public void removeFromMoving(String spriteId) {
        movingNode.remove(spriteId);
    }

    public void removeFromRoom(Room room, String spriteId) {
        Fqn roomFqn = roomFqn(room);
        Node<String, Sprite> roomNode = sceneNode.getChild(roomFqn);
        roomNode.remove(spriteId);
    }

    public void removeFromServer(String spriteId) {
        serverNode.remove(spriteId);
    }

    public void removeFromGhost(String spriteId) {
        dissociateNode.remove(spriteId);
    }

    public Sprite get(String spriteId) {
        return serverNode.get(spriteId);
    }

    public Sprite get(Room room, String spriteId) {
        Object o = sceneNode.getChild(roomFqn(room)).get(spriteId);
        if (o == null) return null;
        return (Sprite) o;
    }

    public Collection<Sprite> listOfSecne(String sceneId) {
//        Collection<Sprite> sprites = new HashSet<Sprite>();
//        Node scene = sceneNode.getChild(Fqn.fromString(sceneId));
//        Set<Node> rooms = scene.getChildren();
//        for(Node room:rooms){
//            sprites.addAll(room.getData().values());
//        }
//        return sprites;
        throw new IllegalStateException("This Method is still not implemented ");
    }

    public Collection<Sprite> listOfRoom(Room room) {
        List<Sprite> list = new ArrayList<Sprite>();
        Node n = sceneNode.getChild(roomFqn(room));
        if (n == null) return null;
        return n.getData().values();
    }

    public Collection<Sprite> listOfMoving() {
        return movingNode.getData().values();
    }

    public Collection<Sprite> listAll() {
        return serverNode.getData().values();
    }

    public Boolean isExist(Room room, String spriteId) {
        return get(room, spriteId) != null;
    }

    /**
     * 根据房间,返回房间的Fqn对象
     *
     * @param room
     */
    private Fqn roomFqn(Room room) {
        return Fqn.fromElements(room.sceneId, room.sceneInstanceId);
    }
}
